package demo2接口使用案例;
//浅拷贝
class Money{
    public double money = 19.9;
}
class Person1 implements Cloneable{
    public int age;
    public Money m;

    public Person1(int age) {
        this.age = age;
        this.m = new Money();//在构造方法中实例化一个money
    }

    @Override
    public String toString() {
        return "Person{" +
                " age=" + age +
                " }";
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Test4 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person1 person1 = new Person1(10);
        Person1 person2 = (Person1) person1.clone();
        System.out.println(person1);
        System.out.println(person2);
        System.out.println("===============");
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);//先调用的是person1的成员变量m，
        //由于在构造方法中进行了m的实例化，所以我还可以调用Money类中的成员变量
        System.out.println("===============");

        //将person2进行修改，正常我们所期望的是只有person2进行修改，person1没有变化
        person2.m.money = 99.99;
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
        //但是可惜的是两者都发生了变化

        //所以发生了这种类似的变化，叫做浅拷贝
        /*
        在虚拟机栈上，会创建两个空间分别是person1和person2，
        person1所实例化的对象会在堆上创建一个对象的空间（地址为0x98），存入两个成员变量，但是其中m是Money类型即是引用类型，
        并且也是实例化了，所以那么也会是创建money类型的对象的空间（地址为0x65），这时候在对中的成员变量m也会得到它实例化的地址
        person1.clone()是把person1指向的对象进行克隆，但是没把这个对象的空间中成员变量m所指的对象进行克隆
        所以那也意味着成员变量m还是指的是0x65的它自己的对象空间Money，这个对象的空间的成员变量是money
        person2还是指的是第一次的对象中的对象的成员变量money；
        所以这个时候堆money的修改还是一次就改变person1和person2所指的money的值，两者还是一样的

        此时这个现象被称之浅拷贝：并没有将对象中的对象去进行克隆
         */
    }
}
